import tkinter as tk
from tkinter import ttk, messagebox
import json5

from utils.static import CONFIG_FILE_PATH

# 安全转换为float，若无法转换则返回默认值（防止输入框为空或非法时报错）
def safe_float(val, default=0.0):
    try:
        return float(val)
    except (ValueError, TypeError):
        return default

# 安全转换为int，若无法转换则返回默认值（防止输入框为空或非法时报错）
def safe_int(val, default=0):
    try:
        return int(val)
    except (ValueError, TypeError):
        return default

class ConfigGeneratorWindow:
    def __init__(self, parent):
        """
        创建配置文件生成器窗口
        
        Args:
            parent: 父窗口，通常是主窗口
        """
        self.parent = parent
        self.config_window = None
        self.is_open = False
        
    def open(self):
        """打开配置文件生成器窗口"""
        # 如果窗口已经打开，则不再创建新窗口
        if self.is_open:
            self.config_window.focus_force()
            return
            
        try:
            # 创建新窗口配置基础框架
            self.config_window = tk.Toplevel(self.parent)
            self.config_window.title("配置文件生成器")
            self.config_window.geometry("900x700")
            # 设置为模态窗口
            self.config_window.transient(self.parent)
            self.config_window.grab_set()
            self.config_window.focus_set()
            # 设置窗口关闭事件
            self.config_window.protocol("WM_DELETE_WINDOW", self.on_close)
            # 标记窗口已打开
            self.is_open = True
            
            # 居中显示窗口
            self.center_window(self.config_window, 900, 700)
            
            notebook = ttk.Notebook(self.config_window)
            notebook.pack(fill='both', expand=True, padx=10, pady=5)
            
            self.config_vars = {}
            
            # 基础设置页
            basic_frame = ttk.Frame(notebook)
            notebook.add(basic_frame, text='基础设置')
            
            self.add_option(basic_frame, "steam_login_ignore_ssl_error", "Steam 登录时是否开启 SSL 验证", ["否", "是"])
            self.add_option(basic_frame, "steam_local_accelerate", "是否开启本地加速功能", ["否", "是"])
            self.add_option(basic_frame, "use_proxies", "是否手动指定 Steam 代理", ["否", "是"])
            self.add_option(basic_frame, "no_pause", "程序错误后是否直接停止运行", ["否", "是"])
            
            proxy_frame = ttk.LabelFrame(basic_frame, text="代理设置")
            proxy_frame.pack(fill='x', padx=5, pady=5)
            self.add_entry(proxy_frame, "proxies_http", "HTTP代理", "http://127.0.0.1:7890")
            self.add_entry(proxy_frame, "proxies_https", "HTTPS代理", "http://127.0.0.1:7890")

            log_frame = ttk.LabelFrame(basic_frame, text="日志设置")
            log_frame.pack(fill='x', padx=5, pady=5)
            self.add_option(log_frame, "log_level", "日志等级", ["debug", "info", "warning", "error"])
            self.add_entry(log_frame, "log_retention_days", "日志保留天数", "7")

            # BUFF设置页
            buff_frame = ttk.Frame(notebook)
            notebook.add(buff_frame, text='BUFF设置')
            
            # BUFF自动发货设置
            buff_accept_frame = ttk.LabelFrame(buff_frame, text="自动发货设置")
            buff_accept_frame.pack(fill='x', padx=5, pady=5)
            self.add_option(buff_accept_frame, "buff_auto_accept_enable", "是否启用BUFF自动发货", ["否", "是"])
            self.add_entry(buff_accept_frame, "buff_auto_accept_interval", "检查新报价的间隔（秒）", "300")
            self.add_option(buff_accept_frame, "buff_auto_accept_sell_protection", "是否开启出售保护", ["否", "是"])
            self.add_entry(buff_accept_frame, "buff_auto_accept_protection_price", "出售保护价格（元）", "30")
            self.add_entry(buff_accept_frame, "buff_protection_price_percentage", "出售价格保护比例", "0.9")

            # 自动上架设置
            buff_sale_frame = ttk.LabelFrame(buff_frame, text="自动上架设置")
            buff_sale_frame.pack(fill='x', padx=5, pady=5)
            self.add_option(buff_sale_frame, "buff_auto_on_sale_enable", "是否启用自动上架", ["否", "是"])
            self.add_option(buff_sale_frame, "buff_force_refresh", "强制刷新库存", ["是", "否"])
            self.add_option(buff_sale_frame, "buff_use_range_price", "使用磨损区间最低价", ["否", "是"])
            self.add_entry(buff_sale_frame, "buff_blacklist_time", "黑名单时间（小时，逗号分隔）", "1,2,3")
            self.add_entry(buff_sale_frame, "buff_whitelist_time", "白名单时间（小时，逗号分隔）", "8,12,16")
            self.add_entry(buff_sale_frame, "buff_random_chance", "随机上架几率(1-100)", "100")
            self.add_entry(buff_sale_frame, "buff_description", "商品上架描述")
            self.add_entry(buff_sale_frame, "buff_check_interval", "检查库存间隔（秒）", "1800")

            # BUFF求购设置
            buff_buy_frame = ttk.LabelFrame(buff_frame, text="求购设置")
            buff_buy_frame.pack(fill='x', padx=5, pady=5)
            self.add_option(buff_buy_frame, "buff_buy_order_enable", "是否供应求购订单", ["否", "是"])
            self.add_option(buff_buy_frame, "buff_buy_order_only_auto_accept", "只供应给开启自动收货的求购订单", ["是", "否"])
            self.add_entry(buff_buy_frame, "buff_buy_order_payment_method", "支持收款方式（逗号分隔）", "支付宝")
            self.add_entry(buff_buy_frame, "buff_buy_order_min_price", "低于多少金额直接塞求购", "5")

            # 悠悠有品设置页
            uu_frame = ttk.Frame(notebook)
            notebook.add(uu_frame, text='悠悠有品设置')

            # UU自动发货设置
            uu_accept_frame = ttk.LabelFrame(uu_frame, text="自动发货设置")
            uu_accept_frame.pack(fill='x', padx=5, pady=5)
            self.add_option(uu_accept_frame, "uu_auto_accept_enable", "是否启用自动发货", ["否", "是"])
            self.add_entry(uu_accept_frame, "uu_auto_accept_interval", "检查新报价的间隔（秒）", "300")

            # UU租赁设置
            uu_lease_frame = ttk.LabelFrame(uu_frame, text="租赁设置")
            uu_lease_frame.pack(fill='x', padx=5, pady=5)
            self.add_option(uu_lease_frame, "uu_auto_lease_enable", "是否启用租赁自动上架", ["否", "是"])
            self.add_entry(uu_lease_frame, "uu_lease_max_days", "最长租赁时间（天）", "60")
            self.add_entry(uu_lease_frame, "uu_lease_min_price", "最低上架价格（元）", "100")
            self.add_entry(uu_lease_frame, "uu_lease_run_time", "每日运行时间（HH:MM）", "17:30")
            self.add_entry(uu_lease_frame, "uu_lease_interval", "修改价格间隔（分钟）", "31")
            self.add_text(uu_lease_frame, "uu_lease_filter_items", "不出租物品列表（每行一个）", height=4)

            # Steam设置页
            steam_frame = ttk.Frame(notebook)
            notebook.add(steam_frame, text='Steam设置')
            
            self.add_option(steam_frame, "steam_auto_accept_enable", "是否启用自动接受礼物", ["否", "是"])
            self.add_entry(steam_frame, "steam_auto_accept_interval", "检查报价间隔（秒）", "300")

            # 预览和保存按钮
            button_frame = ttk.Frame(self.config_window)
            button_frame.pack(fill='x', padx=10, pady=5)
            
            ttk.Button(button_frame, text="预览配置", command=self.preview_config).pack(side='left', padx=5)
            ttk.Button(button_frame, text="保存配置", command=self.save_config).pack(side='left', padx=5)
            ttk.Button(button_frame, text="关闭", command=self.on_close).pack(side='left', padx=5)

            # 新增帮助超链接
            help_link = tk.Label(button_frame, text="不会配置？点击获取帮助文档", fg="#1a73e8", cursor="hand2", font=("Microsoft YaHei", 10, "underline"))
            help_link.pack(side='left', padx=12)

            # 鼠标悬停效果
            def on_link_enter(e):
                help_link.config(fg="#0b59d9")
            def on_link_leave(e):
                help_link.config(fg="#1a73e8")
            help_link.bind("<Enter>", on_link_enter)
            help_link.bind("<Leave>", on_link_leave)
            help_link.bind("<Button-1>", lambda e: self.show_help_dialog())

            # 打开窗口后尝试加载配置文件并填充
            self.load_config_from_file()

        except Exception as e:
            messagebox.showerror("错误", f"无法打开配置文件生成器：{str(e)}")

    def add_option(self, parent, name, text, options):
        """添加下拉选项"""
        frame = ttk.Frame(parent)
        frame.pack(fill='x', padx=5, pady=2)
        ttk.Label(frame, text=text).pack(side='left')
        var = tk.StringVar(value=options[0])
        ttk.Combobox(frame, textvariable=var, values=options, state='readonly').pack(side='right')
        self.config_vars[name] = var
    
    def add_entry(self, parent, name, text, default=""):
        """添加文本输入框"""
        frame = ttk.Frame(parent)
        frame.pack(fill='x', padx=5, pady=2)
        ttk.Label(frame, text=text).pack(side='left')
        var = tk.StringVar(value=default)
        ttk.Entry(frame, textvariable=var).pack(side='right', fill='x', expand=True)
        self.config_vars[name] = var

    def add_text(self, parent, name, text, height=3):
        """添加多行文本框"""
        frame = ttk.Frame(parent)
        frame.pack(fill='x', padx=5, pady=2)
        ttk.Label(frame, text=text).pack(side='left')
        text_widget = tk.Text(frame, height=height)
        text_widget.pack(side='right', fill='x', expand=True)
        self.config_vars[name] = text_widget

    def preview_config(self):
        """预览配置"""
        config = self.generate_config()
        preview = tk.Toplevel(self.config_window)
        preview.title("配置预览")
        preview.geometry("800x600")
        
        text = tk.Text(preview, wrap='none')
        text.pack(fill='both', expand=True)
        
        scrolly = ttk.Scrollbar(preview, orient='vertical', command=text.yview)
        scrollx = ttk.Scrollbar(preview, orient='horizontal', command=text.xview)
        scrolly.pack(side='right', fill='y')
        scrollx.pack(side='bottom', fill='x')
        text.configure(yscrollcommand=scrolly.set, xscrollcommand=scrollx.set)
        
        text.insert('1.0', json5.dumps(config, indent=2))

    def save_config(self):
        """保存配置到文件"""
        try:
            config = self.generate_config()
            with open(CONFIG_FILE_PATH, 'w', encoding='utf-8') as f:
                json5.dump(config, f, indent=2)
            messagebox.showinfo("成功", "配置已保存！")
        except Exception as e:
            messagebox.showerror("错误", f"保存配置失败：{str(e)}")

    def generate_config(self):
        """生成配置字典"""
        config = {}
        
        # 基础设置
        config.update({
            "steam_login_ignore_ssl_error": self.config_vars["steam_login_ignore_ssl_error"].get() == "是",
            "steam_local_accelerate": self.config_vars["steam_local_accelerate"].get() == "是",
            "use_proxies": self.config_vars["use_proxies"].get() == "是",
            "no_pause": self.config_vars["no_pause"].get() == "是",
            "log_level": self.config_vars["log_level"].get(),
            "log_retention_days": safe_int(self.config_vars["log_retention_days"].get()),
        })
        
        if config["use_proxies"]:
            config["proxies"] = {
                "http": self.config_vars["proxies_http"].get(),
                "https": self.config_vars["proxies_https"].get()
            }

        # BUFF设置
        config.update({
            "buff_auto_accept_offer": {
                "enable": self.config_vars["buff_auto_accept_enable"].get() == "是",
                "interval": safe_int(self.config_vars["buff_auto_accept_interval"].get()),
                "sell_protection": self.config_vars["buff_auto_accept_sell_protection"].get() == "是",
                "protection_price": safe_float(self.config_vars["buff_auto_accept_protection_price"].get()),
                "protection_price_percentage": safe_float(self.config_vars["buff_protection_price_percentage"].get())
            },
            "buff_auto_on_sale": {
                "enable": self.config_vars["buff_auto_on_sale_enable"].get() == "是",
                "force_refresh": self.config_vars["buff_force_refresh"].get() == "是",
                "use_range_price": self.config_vars["buff_use_range_price"].get() == "是",
                "blacklist_time": [safe_int(x.strip()) for x in self.config_vars["buff_blacklist_time"].get().split(",") if x.strip() != ''],
                "whitelist_time": [safe_int(x.strip()) for x in self.config_vars["buff_whitelist_time"].get().split(",") if x.strip() != ''],
                "random_chance": safe_int(self.config_vars["buff_random_chance"].get()),
                "description": self.config_vars["buff_description"].get(),
                "check_interval": safe_int(self.config_vars["buff_check_interval"].get())
            },
            "buff_buy_order": {
                "enable": self.config_vars["buff_buy_order_enable"].get() == "是",
                "only_auto_accept": self.config_vars["buff_buy_order_only_auto_accept"].get() == "是",
                "payment_method": [x.strip() for x in self.config_vars["buff_buy_order_payment_method"].get().split(",")],
                "min_price": safe_float(self.config_vars["buff_buy_order_min_price"].get())
            }
        })
        
        # 悠悠有品设置
        config.update({
            "uu_auto_accept_offer": {
                "enable": self.config_vars["uu_auto_accept_enable"].get() == "是",
                "interval": safe_int(self.config_vars["uu_auto_accept_interval"].get())
            },
            "uu_auto_lease": {
                "enable": self.config_vars["uu_auto_lease_enable"].get() == "是",
                "max_days": safe_int(self.config_vars["uu_lease_max_days"].get()),
                "min_price": safe_float(self.config_vars["uu_lease_min_price"].get()),
                "run_time": self.config_vars["uu_lease_run_time"].get(),
                "interval": safe_int(self.config_vars["uu_lease_interval"].get()),
                "filter_items": [x.strip() for x in self.config_vars["uu_lease_filter_items"].get("1.0", tk.END).split("\n") if x.strip()]
            }
        })
        
        # Steam设置
        config.update({
            "steam_auto_accept_offer": {
                "enable": self.config_vars["steam_auto_accept_enable"].get() == "是",
                "interval": safe_int(self.config_vars["steam_auto_accept_interval"].get())
            }
        })
        
        return config

    def load_config_from_file(self):
        """
        读取 config/config.json5 并自动填充到界面控件
        """
        import os
        config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config', 'config.json5')
        if not os.path.exists(config_path):
            return  # 文件不存在时不报错
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                config = json5.load(f)
        except Exception as e:
            messagebox.showwarning("警告", f"读取配置文件失败：{str(e)}")
            return
        # 基础类型直接赋值
        mapping = {
            # 基础设置
            'steam_login_ignore_ssl_error': lambda v: self.config_vars['steam_login_ignore_ssl_error'].set('是' if v else '否'),
            'steam_local_accelerate': lambda v: self.config_vars['steam_local_accelerate'].set('是' if v else '否'),
            'use_proxies': lambda v: self.config_vars['use_proxies'].set('是' if v else '否'),
            'no_pause': lambda v: self.config_vars['no_pause'].set('是' if v else '否'),
            'log_level': lambda v: self.config_vars['log_level'].set(v),
            'log_retention_days': lambda v: self.config_vars['log_retention_days'].set(str(v)),
            # 代理
            'proxies': lambda v: (self.config_vars['proxies_http'].set(v.get('http','')), self.config_vars['proxies_https'].set(v.get('https',''))),
            # BUFF自动发货
            'buff_auto_accept_offer': lambda v: (
                self.config_vars['buff_auto_accept_enable'].set('是' if v.get('enable') else '否'),
                self.config_vars['buff_auto_accept_interval'].set(str(v.get('interval',''))),
                self.config_vars['buff_auto_accept_sell_protection'].set('是' if v.get('sell_protection') else '否'),
                self.config_vars['buff_auto_accept_protection_price'].set(str(v.get('protection_price',''))),
                self.config_vars['buff_protection_price_percentage'].set(str(v.get('protection_price_percentage','')))),
            # BUFF自动上架
            'buff_auto_on_sale': lambda v: (
                self.config_vars['buff_auto_on_sale_enable'].set('是' if v.get('enable') else '否'),
                self.config_vars['buff_force_refresh'].set('是' if v.get('force_refresh') else '否'),
                self.config_vars['buff_use_range_price'].set('是' if v.get('use_range_price') else '否'),
                self.config_vars['buff_blacklist_time'].set(','.join([str(x) for x in v.get('blacklist_time',[])])),
                self.config_vars['buff_whitelist_time'].set(','.join([str(x) for x in v.get('whitelist_time',[])])),
                self.config_vars['buff_random_chance'].set(str(v.get('random_chance',''))),
                self.config_vars['buff_description'].set(v.get('description','')),
                self.config_vars['buff_check_interval'].set(str(v.get('check_interval','')))),
            # BUFF求购
            'buff_buy_order': lambda v: (
                self.config_vars['buff_buy_order_enable'].set('是' if v.get('enable') else '否'),
                self.config_vars['buff_buy_order_only_auto_accept'].set('是' if v.get('only_auto_accept') else '否'),
                self.config_vars['buff_buy_order_payment_method'].set(','.join(v.get('payment_method',[]))),
                self.config_vars['buff_buy_order_min_price'].set(str(v.get('min_price','')))),
            # UU自动发货
            'uu_auto_accept_offer': lambda v: (
                self.config_vars['uu_auto_accept_enable'].set('是' if v.get('enable') else '否'),
                self.config_vars['uu_auto_accept_interval'].set(str(v.get('interval','')))),
            # UU自动租赁
            'uu_auto_lease': lambda v: (
                self.config_vars['uu_auto_lease_enable'].set('是' if v.get('enable') else '否'),
                self.config_vars['uu_lease_max_days'].set(str(v.get('max_days',''))),
                self.config_vars['uu_lease_min_price'].set(str(v.get('min_price',''))),
                self.config_vars['uu_lease_run_time'].set(v.get('run_time','')),
                self.config_vars['uu_lease_interval'].set(str(v.get('interval',''))),
                self.config_vars['uu_lease_filter_items'].delete('1.0', tk.END),
                self.config_vars['uu_lease_filter_items'].insert('1.0', '\n'.join(v.get('filter_items',[])))),
            # Steam自动收礼
            'steam_auto_accept_offer': lambda v: (
                self.config_vars['steam_auto_accept_enable'].set('是' if v.get('enable') else '否'),
                self.config_vars['steam_auto_accept_interval'].set(str(v.get('interval','')))),
        }
        for k, setter in mapping.items():
            if k in config:
                try:
                    setter(config[k])
                except Exception as e:
                    print(f"填充{k}失败: {e}")

    def on_close(self):
        """关闭窗口"""
        if self.config_window:
            self.config_window.grab_release()
            self.config_window.destroy()
            self.config_window = None
            self.is_open = False

    def show_help_dialog(self):
        """显示帮助对话框"""
        help_win = tk.Toplevel(self.config_window)
        help_win.title("获取帮助")
        help_win.geometry("320x200")
        help_win.transient(self.config_window)
        help_win.grab_set()
        help_win.focus_set()
        
        # 居中
        def center_help(win, width, height):
            parent_x = self.config_window.winfo_rootx()
            parent_y = self.config_window.winfo_rooty()
            parent_width = self.config_window.winfo_width()
            parent_height = self.config_window.winfo_height()
            x = parent_x + (parent_width - width) // 2
            y = parent_y + (parent_height - height) // 2
            win.geometry(f"{width}x{height}+{x}+{y}")
            
        center_help(help_win, 320, 200)
        
        # 联系方式内容
        tk.Label(help_win, text="如需人工协助配置文件生成：", font=("Microsoft YaHei", 10), anchor='center', justify='center').pack(pady=(18,8), fill='x')
        tk.Label(help_win, text="QQ群：1025778678", font=("Microsoft YaHei", 11, "bold"), fg="#0078d7").pack(pady=2)
        tk.Label(help_win, text="微信：bja1487580811", font=("Microsoft YaHei", 11, "bold"), fg="#43b244").pack(pady=2)
        tk.Label(help_win, text="添加微信请备注'Steamauto'", font=("Microsoft YaHei", 9), fg="#888888").pack(pady=(8,0))
        
        # 关闭帮助窗口时恢复父窗口的模态状态
        def close_help():
            help_win.destroy()
            # 确保主配置窗口重新获得焦点和模态状态
            self.config_window.focus_set()
            self.config_window.grab_set()
            
        tk.Button(help_win, text="关闭", command=close_help).pack(pady=15)
        
        # 设置关闭事件
        help_win.protocol("WM_DELETE_WINDOW", close_help)

    def center_window(self, window, width, height):
        """居中显示窗口"""
        parent_x = self.parent.winfo_rootx()
        parent_y = self.parent.winfo_rooty()
        parent_width = self.parent.winfo_width()
        parent_height = self.parent.winfo_height()
        
        # 若主窗口还未显示，fallback 到屏幕居中
        if parent_width == 1 or parent_height == 1:
            screen_width = window.winfo_screenwidth()
            screen_height = window.winfo_screenheight()
            x = (screen_width - width) // 2
            y = (screen_height - height) // 2
        else:
            x = parent_x + (parent_width - width) // 2
            y = parent_y + (parent_height - height) // 2
            
        window.geometry(f"{width}x{height}+{x}+{y}")
